<template>
  <div class="bar-wrapper">
    <canvas
      id="bar"
      ref="barCanvasRef"
      :width="customWidth"
      :height="customHeight"
    ></canvas>
  </div>
</template>

<script setup lang="ts">
import { onMounted, ref, reactive, defineProps, withDefaults } from "vue";
interface Props {
  customWidth?: number;
  customHeight?: number;
}
const prop = withDefaults(defineProps<Props>(), {
  customWidth: 600,
  customHeight: 600,
});
const barCanvasRef = ref();
const ctx = ref();
// 柱状图
const width = ref(0);
const height = ref(0);
const widthRadius = ref(0);
const heightRadius = ref(0);

const XYAxisColor = ref("#000000");
const barColor = ref("#6495ED");
const labelColor = ref("#000000");
const barWidth = ref(0);
const XSize = ref(0);
const YSize = ref(0);
const XFullSize = ref(0);
const maxBarTop = ref(0);
const barCount = ref(0);
const barGap = ref(20);
const YCount = ref(10);

let start = ref();

const bar = reactive({
  barData: [
    { value: 1000, label: "苏宁易购" },
    { value: 5000, label: "东方甄选" },
    { value: 1000, label: "淘宝精选" },
    { value: 10000, label: "京东商城" },
    { value: 1000, label: "拼 多 多" },
    { value: 3000, label: "亚 马 逊" },
  ],
});

const clientWidth =
  prop.customWidth || document.body.clientWidth || document.documentElement.clientWidth;

onMounted(() => {
  initCanvas();
  getData();
});

const initCanvas = () => {
  // 初始化柱状图
  const barCanvasDOM = barCanvasRef.value as HTMLCanvasElement;
  barCanvasDOM && barCanvasDOM.setAttribute("width", `${clientWidth}`);
  ctx.value = barCanvasDOM.getContext("2d") as CanvasRenderingContext2D;
  width.value = prop.customWidth || barCanvasDOM.clientWidth;
  height.value = prop.customHeight || barCanvasDOM.clientHeight;

  widthRadius.value = width.value / 2;
  heightRadius.value = height.value / 2;

  XFullSize.value = height.value;
  XSize.value = width.value * 0.8;
  YSize.value = height.value * 0.7;

  // 初始画布背景
  ctx.value.fillStyle = "#ffffff";
  ctx.value.fillRect(0, 0, width.value, height.value);
  // 初始化绘制点 左下角+padding 20px
  ctx.value.beginPath();
  // 预留X轴和Y周的label位置
  ctx.value.translate(80, height.value - 50);
  // 绘制Y轴
  ctx.value.strokeStyle = XYAxisColor.value;
  ctx.value.lineWidth = 2;
  ctx.value.moveTo(0, 0);
  ctx.value.lineTo(0, -YSize.value);
  ctx.value.stroke();
  ctx.value.fillStyle = XYAxisColor.value;
  ctx.value.font = "bold 15px cursive";
  ctx.value.fillText("Y", -2.5, -YSize.value - 5);
  // 绘制X轴
  ctx.value.beginPath();
  ctx.value.moveTo(0, 0);
  ctx.value.lineTo(XSize.value, 0);
  ctx.value.stroke();
  ctx.value.fillStyle = XYAxisColor.value;
  ctx.value.font = "bold 15px cursive";
  ctx.value.fillText("X", XSize.value + 2.5, 0 + 2.5);
};

const getData = () => {
  ctx.value.clearRect(0, 0, width.value, -height.value);
  start.value = 0;
  const data = bar.barData;
  barCount.value = data.length;
  // 总宽度/总量 = barwidth
  barWidth.value = XSize.value / barCount.value - barGap.value;
  // 数据中的最大值
  let maxVal = data.reduce((prev, item) => {
    return Math.max(prev, item.value);
  }, 0);

  // 平均每一份多少px
  let avg = (YSize.value - maxBarTop.value) / maxVal;
  data.forEach((item, index) => {
    ctx.value.beginPath();
    ctx.value.fillStyle = barColor.value;
    // +1 是为了每次都增加一个间隔
    ctx.value.fillRect(
      (index + 1) * barGap.value + index * barWidth.value,
      0,
      barWidth.value,
      -(avg * item.value)
    );
    ctx.value.beginPath();
    ctx.value.textAlign = "left";
    ctx.value.fillText(
      `${item.value}`,
      (index + 1) * barGap.value + index * barWidth.value,
      -(avg * item.value + 10)
    );
  });

  // 绘制XY轴label
  data.forEach((item, index) => {
    ctx.value.beginPath();
    ctx.value.fillStyle = labelColor.value;
    ctx.value.fillText(
      `${item.label}`,
      (index + 1) * barGap.value + index * barWidth.value,
      20
    );
  });

  for (let index = 0; index < YCount.value; index++) {
    // （平均每条数据中的1占用几个Y轴PX）*（最高值/10个点）
    let yLabelHeight = ((YSize.value / maxVal) * maxVal) / YCount.value;
    ctx.value.beginPath();
    ctx.value.strokeStyle = labelColor.value;
    ctx.value.textAlign = "center";
    ctx.value.moveTo(1, -(index * yLabelHeight));
    if (!index || index % 2 === 0) {
      ctx.value.lineTo(-20, -(index * yLabelHeight));
      ctx.value.fillText((index * maxVal) / YCount.value, -40, -(index * yLabelHeight));
    } else {
      ctx.value.lineTo(-10, -(index * yLabelHeight));
      ctx.value.fillText(
        `${(index * maxVal) / YCount.value}`,
        -40,
        -(index * yLabelHeight)
      );
    }
    ctx.value.stroke();
    ctx.value.beginPath();
    if (index == YCount.value - 1) {
      console.log("最后一个");
    }
  }
};
</script>

<style></style>
